package main

import (
	"net"
	"strconv"
	"strings"
)

type User struct {
	Name   string
	Addr   string
	C      chan string
	Conn   net.Conn
	server *Server
	logger Logger
}

// 创建用户
func NewUser(conn net.Conn, server *Server) *User {
	userAddr := conn.RemoteAddr().String()

	user := &User{
		Name:   userAddr,
		Addr:   userAddr,
		C:      make(chan string),
		Conn:   conn,
		server: server,
		logger: Logger{},
	}
	go user.ListenMessage()
	return user
}

// Online 用户上线
func (user *User) Online() {
	// 加锁
	user.server.mapLock.Lock()
	user.server.OnlineMap[user.Name] = user
	user.server.mapLock.Unlock()
	user.server.BroadCast(user, "已上线")
	user.logger.Success("当前在线用户数：" + strconv.Itoa(len(user.server.OnlineMap)))
}

// Offline 用户下线
func (user *User) Offline() {
	user.server.BroadCast(user, "下线")
	user.server.mapLock.Lock()
	// 删除下线用户
	delete(user.server.OnlineMap, user.Name)
	user.server.mapLock.Unlock()
}

// DoMessage 用户消息处理
func (user *User) DoMessage(msg string) {
	// 更改用户名
	if len(msg) > 7 && msg[:7] == "rename|" {
		newName := strings.Split(msg, "|")[1]
		_, ok := user.server.OnlineMap[newName]
		if ok {
			user.SendMsg("当前用户名已存在！")
			return
		}
		user.server.mapLock.Lock()
		delete(user.server.OnlineMap, user.Name)
		user.Name = newName
		user.server.OnlineMap[newName] = user
		user.server.mapLock.Unlock()
		user.SendMsg("用户名更改成功！")
		return
	}
	// 私聊
	if len(msg) > 4 && msg[:3] == "to|" {
		info := strings.Split(msg, "|")
		remoteUserName := info[1]
		if remoteUserName == "" {
			user.SendMsg("请输入正确私聊格式\"to|用户名｜消息内容\"\n")
			return
		}

		remoteUser, ok := user.server.OnlineMap[remoteUserName]
		if !ok {
			user.SendMsg("用户不存在！")
			return
		}

		content := info[2]
		if content == "" {
			user.SendMsg("消息内容不能为空")
			return
		}

		remoteUser.SendMsg(user.Name + ": " + content)
		return
	}

	switch msg {
	case "who":
		user.ShowOnlineUsers()
		break
	default:
		// 广播用户消息
		user.server.BroadCast(user, msg)
	}

}

// 发送在线用户
func (user *User) ShowOnlineUsers() {
	user.server.mapLock.Lock()
	for c, _ := range user.server.OnlineMap {
		msg := "[" + c + "] 在线\n"
		user.SendMsg(msg)
	}
	user.server.mapLock.Unlock()
}

// 向对端客户端发送消息
func (user *User) SendMsg(msg string) {
	user.logger.Info("[send] 服务端响应内容：" + msg + " | 来源：" + user.Conn.RemoteAddr().String())
	user.Conn.Write([]byte(msg))
}

func (this *User) ListenMessage() {

	for {
		msg := <-this.C
		this.logger.Info("[send] 服务端响应内容：" + msg + " | 来源：" + this.Conn.RemoteAddr().String())
		this.Conn.Write([]byte(msg + "\n"))
	}
}
